package com.ants.modules.leavingMessage.controller;

import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.ants.common.annotation.AutoLog;
import com.ants.common.annotation.RateLimiter;
import com.ants.common.system.query.QueryGenerator;
import com.ants.common.system.result.Result;
import com.ants.common.utils.IPUtils;
import com.ants.modules.sensitiveWord.utils.SensitiveHighlightProcessor;
import com.ants.modules.sensitiveWord.utils.SensitiveWordUtil;
import com.ants.modules.leavingMessage.entity.LeaveMessage;
import com.ants.modules.leavingMessage.entity.LeaveMessageUser;
import com.ants.modules.leavingMessage.service.LeaveMessageService;
import com.ants.modules.leavingMessage.service.LeaveMessageUserService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import eu.bitwalker.useragentutils.OperatingSystem;
import eu.bitwalker.useragentutils.UserAgent;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

/**
 * TODO
 * Author Chen
 * Date   2022/8/11 18:44
 */

@Slf4j
@Api(tags = "留言")
@RestController
@RequestMapping("/leaveMessage")
public class LeaveMessageController {

    @Autowired
    LeaveMessageService leaveMessageService;
    @Autowired
    LeaveMessageUserService leaveMessageUserService;
    @Autowired
    AmqpTemplate rabbitTemplate;

    @AutoLog(value = "管理端-留言-列表")
    @ApiOperation(value = "管理端--列表", notes = "管理端--列表")
    @GetMapping("/admimList")
    public Result<?> admimList(LeaveMessage leaveMessage,
                               @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                               @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
                               HttpServletRequest req) {
        QueryWrapper<LeaveMessage> queryWrapper = QueryGenerator.initQueryWrapper(leaveMessage, req.getParameterMap());
        queryWrapper.isNull("pid");
        queryWrapper.orderByDesc("create_date");
        Page<LeaveMessage> page = new Page<LeaveMessage>(pageNo, pageSize);
        IPage<LeaveMessage> pageList = leaveMessageService.page(page, queryWrapper);
        return Result.ok(pageList);
    }

    @AutoLog(value = "管理端-留言-列表")
    @ApiOperation(value = "管理端--列表", notes = "管理端--列表")
    @GetMapping("/admimChidList")
    public Result<?> admimChidList(LeaveMessage leaveMessage,
                                   @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                   @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
                                   HttpServletRequest req) {
        QueryWrapper<LeaveMessage> queryWrapper = QueryGenerator.initQueryWrapper(leaveMessage, req.getParameterMap());
        queryWrapper.orderByDesc("create_date");
        Page<LeaveMessage> page = new Page<LeaveMessage>(pageNo, pageSize);
        IPage<LeaveMessage> pageList = leaveMessageService.page(page, queryWrapper);
        return Result.ok(pageList);
    }

    @RateLimiter
    @AutoLog(value = "留言-列表")
    @ApiOperation(value = "留言-列表", notes = "留言-列表")
    @GetMapping("/list")
    public Result<?> queryPageList(LeaveMessage leaveMessage,
                                   @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                   @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
                                   HttpServletRequest req) {
        LambdaQueryWrapper<LeaveMessage> lqw = new LambdaQueryWrapper<>();
        lqw.orderByDesc(LeaveMessage::getCreateTime);
        List<LeaveMessage> list = leaveMessageService.list(lqw);
        int size = list.size();
        IPage<LeaveMessage> pageList = new Page<>();
        for (LeaveMessage record : list) {
            record.setLabel("未审核");
            LeaveMessageUser commentUser = leaveMessageUserService.getById(record.getCommentUserId());
            LeaveMessageUser targetUser = leaveMessageUserService.getById(record.getTargetUserId());
            record.setCommentUser(commentUser);
            record.setTargetUser(targetUser);
        }
        List<LeaveMessage> childPerms = getChildPerms(list);
//        int currentIndex = pageNo > 1 ? (pageNo - 1) * pageSize : 0;
        List<LeaveMessage> list1 = startPage(childPerms, pageNo, pageSize);
        for (LeaveMessage childPerm : list1) {
            childPerm.getChildrenList().sort(Comparator.comparing(LeaveMessage::getCreateTime));
        }
        pageList.setRecords(list1);
        pageList.setTotal(childPerms.size());
        pageList.setSize(size);
        return Result.ok(pageList);
    }

    /**
     * 开始分页
     *
     * @param list
     * @param pageNum  页码
     * @param pageSize 每页多少条数据
     */
    public static <T> List<T> startPage(List<T> list, Integer pageNum, Integer pageSize) {

        if (ObjectUtil.isEmpty(list)) {
            return list;
        }
        if (pageSize == 0 || pageNum == 0) {
            return new ArrayList<T>();
        }

        // 记录总数
        Integer count = list.size();

        // 页数
        int pageCount = 0;
        if (count % pageSize == 0) {
            pageCount = count / pageSize;
        } else {
            pageCount = count / pageSize + 1;
        }

        // 开始索引
        int fromIndex = 0;
        // 结束索引
        int toIndex = 0;

        fromIndex = (pageNum - 1) * pageSize > count ? Math.max(count - pageSize, 0) : (pageNum - 1) * pageSize;
        if (pageNum != pageCount) {
            toIndex = fromIndex + pageSize > count ? count : fromIndex + pageSize;
        } else {
            toIndex = count;
        }

        return list.subList(fromIndex, toIndex);
    }

    public static List<LeaveMessage> getChildPerms(List<LeaveMessage> allMenuList) {
        List<LeaveMessage> rootList = new ArrayList<>();
        for (Iterator<LeaveMessage> lt = allMenuList.iterator(); lt.hasNext(); ) {
            LeaveMessage menu = lt.next();
            if (StringUtils.isBlank(menu.getPid())) {
                rootList.add(menu);
                lt.remove();
            }
        }

        for (LeaveMessage menu : rootList) {
            menu.setChildrenList(getChild(allMenuList, menu.getId()));
        }
        return rootList;
    }

    public static List<LeaveMessage> getChild(List<LeaveMessage> allMenuList, String id) {
        List<LeaveMessage> childList = new ArrayList<>();

        for (Iterator<LeaveMessage> lt = allMenuList.iterator(); lt.hasNext(); ) {
            LeaveMessage menu = lt.next();
            if (menu.getPid().equals(id)) {
                childList.add(menu);
                lt.remove();
            }
        }

        for (LeaveMessage menu : childList) {
            menu.setChildrenList(getChild(allMenuList, menu.getId()));
        }
        return childList;
    }

    /**
     * 添加
     *
     * @param leaveMessage
     * @return
     */
    @RateLimiter
    @AutoLog(value = "留言-添加")
    @ApiOperation(value = "留言-添加", notes = "留言-添加")
    @PostMapping(value = "/add")
    public Result<?> add(@RequestBody LeaveMessage leaveMessage, HttpServletRequest req) {
//        String newText = SensitiveWordUtil.sensitiveFilter(leaveMessage.getContent(), false, new SensitiveDefaultProcessor());
        String newText = SensitiveWordUtil.sensitiveFilter(leaveMessage.getContent(), false, new SensitiveHighlightProcessor());
        if (!newText.equals(leaveMessage.getContent())) {
            return Result.error(100001, "<strong>你的留言：</strong>" + newText + "</br></br>     <strong>注意你的言辞哈，在瞎说话封了你！</strong>");
        }
        String avatar = "";
        try {
            avatar = genLeaveMessage(leaveMessage, req);
        } catch (Exception e) {
            return Result.error("操作失败!");

        }
        Map<String, String> map = new HashMap<>();
        map.put("name", leaveMessage.getNickname());
        map.put("message", leaveMessage.getContent());
        rabbitTemplate.convertAndSend("leavingMessagePushQueue", map);
        return Result.ok(avatar);
    }


    /**
     * 回复
     *
     * @return
     */
    @RateLimiter
    @AutoLog(value = "留言-回复")
    @ApiOperation(value = "留言-回复", notes = "留言-回复")
    @PostMapping(value = "/addReply")
    public Result<?> addReply(@RequestBody LeaveMessage leaveMessage, HttpServletRequest req) {
        String newText = SensitiveWordUtil.sensitiveFilter(leaveMessage.getContent(), false, new SensitiveHighlightProcessor());
        if (!newText.equals(leaveMessage.getContent())) {
            return Result.error(100001, "<strong>你的留言：</strong>" + newText + "</br></br>     <strong>注意你的言辞哈，在瞎说话封了你！</strong>");
        }
        String avatar = "";
        try {
            avatar = genLeaveMessage(leaveMessage, req);
        } catch (Exception e) {
            return Result.error("操作失败!");
        }
        String pId = leaveMessage.getPid();
        LeaveMessage byId = leaveMessageService.getById(pId);
        String userId = leaveMessage.getCommentUserId();
        LeaveMessageUser leaveMessageUser = leaveMessageUserService.getById(userId);

        Map<String, String> map = new HashMap<>();
        map.put("name", leaveMessageUser.getNickName());
        map.put("email", byId.getEmail());
        map.put("message", leaveMessage.getContent());
        map.put("nickname", byId.getNickname());
        map.put("content", byId.getContent());
        rabbitTemplate.convertAndSend("leavingMessageReolyQueue", map);

        return Result.ok(avatar);
    }


    /**
     * 编辑
     *
     * @param leaveMessage
     * @return
     */
    @AutoLog(value = "留言-编辑")
    @ApiOperation(value = "留言-编辑", notes = "留言-编辑")
    @PutMapping(value = "/edit")
    public Result<?> edit(@RequestBody LeaveMessage leaveMessage) {
        boolean b = leaveMessageService.updateById(leaveMessage);

        Map<String, String> map = new HashMap<>();
        map.put("mail", leaveMessage.getEmail());
        map.put("status", "1".equals(leaveMessage.getStatus()) ? "审核不通过" : "审核通过");
        map.put("message", leaveMessage.getContent());
        rabbitTemplate.convertAndSend("leavingMessageCheckQueue", map);
        if (b) {
            return Result.ok("操作成功!");
        }
        return Result.error("操作失败!");
    }

    @GetMapping("/getLeaveMessageCountByPid")
    public Result<?> getLeaveMessageCountByPid(@RequestParam String pid) {
        LambdaQueryWrapper<LeaveMessage> lqw = new LambdaQueryWrapper<>();
        lqw.eq(LeaveMessage::getPid, pid);
        long count = leaveMessageService.count(lqw);
        return Result.ok(count);
    }

    /**
     * @param id
     * @return
     * @功能：删除
     */
    @AutoLog(value = "留言-删除")
    @ApiOperation(value = "留言-编辑", notes = "留言-删除")
    @DeleteMapping("/delete")
    @Transactional(rollbackFor = Exception.class)
    public Result<?> delete(@RequestParam(name = "id", required = true) String id) {
        LeaveMessage leaveMessage = leaveMessageService.getById(id);

        LambdaQueryWrapper<LeaveMessage> lqw = new LambdaQueryWrapper<>();
        lqw.eq(LeaveMessage::getPid, id);
        List<LeaveMessage> listChild = leaveMessageService.list(lqw);
        List<String> ids = new ArrayList<>();
        ids.add(leaveMessage.getCommentUserId());
        for (LeaveMessage message : listChild) {
            ids.add(message.getCommentUserId());
        }
        // 删除留言
        leaveMessageService.removeById(id);
        // 删除回复
        leaveMessageService.remove(lqw);
        if (!ids.isEmpty()) {
            // 删除 人员信息
            leaveMessageUserService.removeByIds(ids);
        }
        return Result.ok("操作成功");
    }

    /**
     * @param id
     * @return
     * @功能：删除
     */
    @DeleteMapping("/deleteChild")
    @Transactional(rollbackFor = Exception.class)
    public Result<?> deleteChild(@RequestParam(name = "id", required = true) String id) {
        LeaveMessage leaveMessage = leaveMessageService.getById(id);

        // 删除回复
        leaveMessageService.removeById(id);
        // 删除 人员信息
        leaveMessageUserService.removeById(leaveMessage.getCommentUserId());
        return Result.ok("操作成功");
    }

    /**
     * @param ids
     * @return
     * @功能：批量删除
     */
    @DeleteMapping("/deleteBatch")
    public Result<?> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
        boolean ok = leaveMessageService.removeByIds(Arrays.asList(ids.split(",")));
        if (ok) {
            return Result.ok("删除成功");
        }
        return Result.error("删除失败");
    }

    @Transactional(rollbackFor = Exception.class)
    public String genLeaveMessage(LeaveMessage leaveMessage, HttpServletRequest req) {
        leaveMessage.setCreateDate(new Date());
        String userId = IdUtil.simpleUUID();
        leaveMessage.setCommentUserId(userId);
        String agentStr = req.getHeader("user-agent");
        UserAgent agent = UserAgent.parseUserAgentString(agentStr);
        String browser = IPUtils.getBrowser(req);
        leaveMessage.setBrowser(browser);
        String ip = IPUtils.getIpAddress(req);
        leaveMessage.setIp(ip);
        String ipAddress = IPUtils.getLocalCityInfo(ip);
        leaveMessage.setIpAddr(ipAddress);

        OperatingSystem os = agent.getOperatingSystem();
        leaveMessage.setOsName(os.getName());
        leaveMessage.setStatus("0");
        leaveMessageService.save(leaveMessage);
        LeaveMessageUser leaveMessageUser = new LeaveMessageUser();
        leaveMessageUser.setId(userId);
        leaveMessageUser.setNickName(leaveMessage.getNickname());
        if (StrUtil.isBlank(leaveMessage.getAvatar())) {
            // 在壁纸中随机抽取一张图片作为 头像
            String avatar = leaveMessageService.getRandomAvatar();
            leaveMessageUser.setAvatar(avatar);
        } else {
            leaveMessageUser.setAvatar(leaveMessage.getAvatar());
        }
        leaveMessageUserService.save(leaveMessageUser);
        return leaveMessageUser.getAvatar();
    }
}
